import jwt
import datetime
from functools import wraps
from flask import request, jsonify, current_app


def generate_token(user_info, expires_delta=None):
    """
    生成JWT token
    
    参数：
        user_info: 用户信息字典
        expires_delta: 过期时间，默认为1小时
    
    返回：
        JWT token字符串
    """
    if expires_delta is None:
        expires_delta = datetime.timedelta(hours=1)

    expires_at = datetime.datetime.now() + expires_delta

    payload = {
        'userInfo': user_info,
        'sub': str(user_info.get('user_id', '')),
        'exp': expires_at
    }

    secret_key = current_app.config.get('SECRET_KEY', '1231撒大苏打sd123125————0das')
    token = jwt.encode(payload, secret_key, algorithm='HS256')

    return token


def token_required(f):
    """
    验证Token的装饰器
    
    使用方式：
    @token_required
    def your_api_function():
        ...
    """

    @wraps(f)
    def decorated_function(*args, **kwargs):
        token = None

        # 从Authorization头中获取token
        auth_header = request.headers.get('Authorization')
        if auth_header:
            try:
                token = auth_header.split(" ")[1]  # 提取 Bearer token 格式中的token部分
            except IndexError:
                token = auth_header

        # 如果请求中没有token，尝试从查询参数获取
        if not token:
            token = request.args.get('token')

        # 如果请求中没有token，尝试从表单获取
        if not token:
            token = request.form.get('token')

        # 如果请求中没有token，尝试从JSON数据获取
        if not token and request.is_json:
            token = request.json.get('token')

        # 如果没有找到token
        if not token:
            return jsonify({
                "code": 401,
                "msg": "缺少Token，请先登录"
            }), 401

        # 验证token
        try:
            secret_key = current_app.config.get('SECRET_KEY', '1231撒大苏打sd123125————0das')
            payload = jwt.decode(token, secret_key, algorithms=["HS256"])
            current_app.logger.info(f"token 验证成功: {request.path}")

            # 将用户信息添加到请求中，方便后续使用
            request.user_info = payload.get('userInfo')

        except jwt.ExpiredSignatureError:
            return jsonify({
                "code": 401,
                "msg": "Token已过期，请重新登录"
            }), 401

        except jwt.InvalidTokenError:
            return jsonify({
                "code": 401,
                "msg": "无效的Token"
            }), 401

        # 继续执行被装饰的函数
        return f(*args, **kwargs)

    return decorated_function


def get_current_user():
    """
    获取当前请求的用户信息
    
    返回：
        用户信息字典或None
    """
    if hasattr(request, 'user_info'):
        return request.user_info
    return None
